# -*- coding: utf-8 -*-

"""
* Copyright (C) 2016 GridSafe, Inc.
"""
import io
import os
import json
import string
import uuid
import random
from urllib.parse import urlencode
from django.contrib.auth.decorators import login_required
from PIL import Image, ImageFont, ImageDraw
from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse as url_reverse
from django.core.urlresolvers import reverse
from django.db import transaction
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect, render
from apps.wallet.util.utils import flash
from django.template.response import TemplateResponse
from django.views.decorators.csrf import csrf_exempt
from apps.wallet import constants
from django.contrib.auth import authenticate, login, logout
from apps.wallet.models.profile import Profile
from apps.wallet.util.utils import api_fail_response, api_success_response
from apps.wallet.forms import LoginForm, RegisterForm, AddAccountForm, ResetPWForm


@csrf_exempt
def user_login(request):
    if request.method == "POST":
        if request.META.get('CONTENT_TYPE') == "application/json":
            body_unicode = request.body.decode('utf-8')
            body = json.loads(body_unicode)
            username = body.get('username')
            password = body.get('password')
            import re
            if (not username) or (not password):
                return api_fail_response(constants.ARGUMENT_MISSING,
                                         "Email or password is missing.")
            if re.match('1[3|5|7|8|][0-9]{9}', username):
                _user = Profile.objects.filter(phone=username).first()
            elif re.match('[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}', username):
                _user = Profile.objects.filter(email=username).first()
            else:
                _user = Profile.objects.filter(username=username).first()

            if _user:
                user = authenticate(username=_user.username, password=password)
                if user is not None and user.is_active:
                    return api_success_response({"code": constants.OPERATION_SUCCESS,
                                                 "message": 'success'})
            else:
                return api_fail_response(constants.ERROR_ARGUMENT,
                                         "Email or password is incorrect.")
        else:
            form = LoginForm(request.POST)
            if form.is_valid():
                email = form.cleaned_data['email']
                password = form.cleaned_data['password']
                if email.isdigit():
                    _user = User.objects.filter(username=email).first()
                else:
                    _user = User.objects.filter(email=email).first()
                if _user:
                    user = authenticate(username=_user.username,
                                        password=password)
                    if user is not None and user.is_active:
                        login(request, user)
                        return redirect(reverse('homepage'))
                # 登录失败
                form.add_error("email", "账户不存在或密码不正确")
    else:
        form = LoginForm()
    return TemplateResponse(request=request, template='app/auth/login.html', context={'form': form})


@login_required
def user_logout(request):
    logout(request)
    return redirect(reverse('login'))


def register_user(request):
    if request.method == "POST":
        if request.META.get('CONTENT_TYPE') == "application/json":
            body_unicode = request.body.decode('utf-8')
            body = json.loads(body_unicode)
            username = body.get('username')
            password1 = body.get('password1')
            password2 = body.get('password2')
            if password1 != password2:
                return api_fail_response(constants.ERROR_MESSAGES, 'PASSWORD is correct')
            try:
                User.objects.get(username=username)
            except User.DoesNotExist:
                _user = User.objects.create_user(username=username,
                                                 password=password1)
                _user.save()
                return api_success_response({'code': constants.OPERATION_SUCCESS, 'message': 'success'})
        else:
            form = RegisterForm(request.POST)
            if form.is_valid():
                phone = form.cleaned_data['phone']
                password1 = form.cleaned_data['password1']
                password2 = form.cleaned_data['password2']
                if password1 != password2:
                    flash(request, '输入有误', '前后密码不一致')
                    return render(request, 'app/auth/register.html',
                                  {"form": form})

                try:
                    User.objects.get(username=phone)
                except User.DoesNotExist:

                    user = User.objects.create_user(username=phone,
                                                    password=password1)
                    user.save()
                    return redirect(reverse('login'))
                else:
                    flash(request, '输入有误', '用户名已注册')
                    return render(request, 'app/auth/register.html',
                                  {"form": form})
    else:
        form = RegisterForm()
    return TemplateResponse(request=request,
                            template='app/auth/register.html',
                            context={"form": form})


def cache_pic(request, *args, **kwargs):
    image = Image.new('RGB', (147, 49), color=(255, 255, 255))  # model, size, background color
    font_file = os.path.join(settings.BASE_DIR, 'static/fonts/ARIAL.TTF')  # choose a font file
    font = ImageFont.truetype(font_file, 47)  # the font object
    draw = ImageDraw.Draw(image)
    rand_str = ''.join(random.sample(string.ascii_letters + string.digits, 4))  # The random string
    draw.text((7, 0), rand_str, fill=(0, 0, 0), font=font)  # position, content, color, font
    del draw
    request.session['captcha'] = rand_str.lower()  # store the content in Django's session store
    buf = io.BytesIO()  # a memory buffer used to store the generated image
    image.save(buf, 'jpeg')
    return HttpResponse(buf.getvalue(),
                        'image/jpeg')  # return the image data stream as image/jpeg format, browser will treat it as an image


def user_reset_pw(request, user_id):
    if request.method == 'POST':
        form = ResetPWForm(request.POST)
        if form.is_valid():
            user = get_object_or_404(User, id=user_id)
            if (request.user == user) or \
                    (request.user in user.profile.parent.all()):
                old_password = form.cleaned_data['old_password']

                result = user.check_password(old_password)

                password1 = form.cleaned_data['password1']
                password2 = form.cleaned_data['password2']
                if password1 == password2 and result:
                    user.set_password(password1)
                    user.save()
                    return redirect(reverse('homepage'))
                else:
                    form.add_error("old_password", "输入密码不一致或原密码不正确")

    else:
        form = ResetPWForm()
        get_object_or_404(User, id=user_id)
    return render(request,
                  'app/auth/reset_pw.html',
                  {'form': form, 'user_id': user_id})


@transaction.atomic
def add_account(request):
    if not request.user.profile.is_super:
        raise Http404

    if request.method == 'POST':
        form = AddAccountForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            password1 = form.cleaned_data['password1']
            password2 = form.cleaned_data['password2']
            if password1 == password2:
                user = User(username=username,
                            email=email)
                user.set_password(password1)
                user.save()

                profile = Profile.objects.get(user=user)
                profile.parent.add(request.user)
                profile.save(update_fields=('parent',))
                return redirect(
                    "{}?user_id={}".format(reverse('homepage'), user.id))
            else:
                form.add_error("password1", "输入密码不一致")
